﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;

namespace Bitcoin.IO
{
    public static class BinaryWriterExtension
    {
        public static void Write(this BinaryWriter writer, Transaction value)
        {
            writer.Write(value.Version);
            writer.WriterVarIntEncoded((ulong)value.Inputs.Count);
            foreach (var input in value.Inputs)
            {
                writer.Write(input);
            }
            writer.WriterVarIntEncoded((ulong)value.Outputs.Count);
            foreach (var output in value.Outputs)
            {
                writer.Write(output);
            }
            writer.Write(value.LockTime);
        }

        public static void Write(this BinaryWriter writer, TransactionInput value)
        {
            writer.Write(value.Outpoint.Hash.Bytes);
            writer.Write((UInt32) value.Outpoint.Index);
            writer.WriterVarIntEncoded((UInt64) value.ScriptBytes.Length);
            writer.Write(value.ScriptBytes);
            writer.Write((UInt32) value.Sequence);
        }

        public static void Write(this BinaryWriter writer, TransactionOutput value)
        {
            Debug.Assert(value.ScriptBytes != null);

            writer.Write((UInt64) value.Value);
            writer.WriterVarIntEncoded((UInt64) value.ScriptBytes.Length);
            writer.Write(value.ScriptBytes);
        }

        public static void WriterVarIntEncoded(this BinaryWriter writer, UInt64 value)
        {
            if (value < 0xfd)
            {
                writer.Write((Byte)value);
            }
            else if (value <= UInt16.MaxValue)
            {
                writer.Write((Byte) 0xfd);
                writer.Write((UInt16) value);
            }
            else if (value <= UInt32.MaxValue)
            {
                writer.Write((Byte)0xfe);
                writer.Write((UInt32)value);
            }
            else
            {
                writer.Write((Byte)0xff);
                writer.Write(value);
            }
        }
    }
}
